﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using FIFP.Common;
using System.Collections.Generic;
using FIFP.DashBoard.Model;
using FIFP.DashBoard.Helper;
using System.Linq;
using System.ComponentModel;
using System.Collections.ObjectModel;
using Telerik.Windows.Controls;

namespace FIFP.DashBoard.ViewModel
{
    public class FilterVM : ViewModelCore
    {
        #region Variables
        private DateTime displayEndDate = new DateTime(DateTime.Now.Year, 12, 31);
        private DateTime displayStartDate = new DateTime(DateTime.Now.Year, 1, 1);
        private DateTime startDate = new DateTime(DateTime.Now.Year, 1, 1);
        private DateTime endDate = new DateTime(DateTime.Now.Year, 12, 31);
        //public event EventHandler<CustomEventArgs<AppointmentGroup>> OnAppointmentDataCompleted;
        private List<string> selectedFluids = new List<string>();
        private List<string> selectedUnitTypes = new List<string>();
        public event EventHandler<CustomEventArgs<AppointmentGroup>> OnAppointmentDataCompleted;
        public event EventHandler OnCombinedTowerClick;
        #endregion

        #region Properties

        public DateTime DisplayStartDate
        {
            get { return displayStartDate; }
            set { SetPropertyValue(() => DisplayStartDate, value, val => displayStartDate = val); }
        }

        public DateTime DisplayEndDate
        {
            get { return displayEndDate; }
            set { SetPropertyValue(() => DisplayEndDate, value, val => displayEndDate = val); }
        }

        public DateTime StartDate
        {
            get { return startDate; }
            set
            {
                if (startDate != value)
                {
                    startDate = value;
                    OnPropertyChanged(() => this.StartDate);
                }
            }
        }

        public DateTime EndDate
        {
            get { return endDate; }
            set
            {
                if (endDate != value)
                {
                    endDate = value;
                    OnPropertyChanged(() => this.EndDate);
                }
            }
        }


        private List<string> divisionList = new List<string>();
        public List<string> DivisionList
        {
            get { return divisionList; }
            set { SetPropertyValue(() => DivisionList, value, val => divisionList = val); }
        }

        private List<Fluid> fluidList = new List<Fluid>();
        public List<Fluid> FluidList
        {
            get { return fluidList; }
            set { SetPropertyValue(() => FluidList, value, val => fluidList = val); }
        }

        private List<string> unitTypeList = new List<string>();
        public List<string> UnitTypeList
        {
            get { return unitTypeList; }
            set { SetPropertyValue(() => UnitTypeList, value, val => unitTypeList = val); }
        }

        private List<string> facilityList = new List<string>();
        public List<string> FacilityList
        {
            get { return facilityList; }
            set { SetPropertyValue(() => FacilityList, value, val => facilityList = val); }
        }

        private string selectedUnitType;
        public string SelectedUnitType
        {
            get { return selectedUnitType; }
            set { SetPropertyValue(() => SelectedUnitType, value, val => selectedUnitType = val); }
        }

        private string selectedFluidType;
        public string SelectedFluidType
        {
            get { return selectedFluidType; }
            set { SetPropertyValue(() => SelectedFluidType, value, val => selectedFluidType = val); }
        }


        private string selectedDivision;
        public string SelectedDivision
        {
            get { return selectedDivision; }
            set
            {
                if (selectedDivision != value)
                {
                    selectedDivision = value;
                    OnPropertyChanged(() => this.SelectedDivision);
                }
            }
        }

        private bool isFilterEnabled = false;
        public bool IsFilterEnabled
        {
            get { return isFilterEnabled; }
            set { SetPropertyValue(() => IsFilterEnabled, value, val => isFilterEnabled = val); }
        }

        private bool isDivisionEnabled = false;
        public bool IsDivisionEnabled
        {
            get { return isDivisionEnabled; }
            set { SetPropertyValue(() => IsDivisionEnabled, value, val => isDivisionEnabled = val); }
        }

        private Visibility isDateTimeVisibility = Visibility.Visible;
        public Visibility IsDateTimeVisibility
        {
            get { return isDateTimeVisibility; }
            set { SetPropertyValue(() => IsDateTimeVisibility, value, val => isDateTimeVisibility = val); }
        }

        private bool isCombinedTowerChecked = false;
        public bool IsCombinedTowerChecked
        {
            get { return isCombinedTowerChecked; }
            set { SetPropertyValue(() => IsCombinedTowerChecked, value, val => isCombinedTowerChecked = val); }
        }

        private Visibility isCombinedTowerVisibility = Visibility.Collapsed;
        public Visibility IsCombinedTowerVisibility
        {
            get { return isCombinedTowerVisibility; }
            set { SetPropertyValue(() => IsCombinedTowerVisibility, value, val => isCombinedTowerVisibility = val); }
        }

        #endregion

        #region Commands



        private ICommand _FilterCommand;
        public ICommand FilterCommand
        {
            get
            {
                return _FilterCommand ??
                        (_FilterCommand = new RelayCommand<Button>(FilterAppointmentByFluidAndUnitType));
            }
        }



        private ICommand _DivisionSelectionCommand;
        public ICommand DivisionSelectionCommand
        {
            get
            {
                return _DivisionSelectionCommand ??
                        (_DivisionSelectionCommand = new RelayCommand<ComboBox>(DivisionFilter));
            }
        }



        private ICommand _CheckedFluidEvent;
        public ICommand CheckedFluidEvent
        {
            get
            {
                return _CheckedFluidEvent ??
                        (_CheckedFluidEvent = new RelayCommand<CheckBox>(FluidFilter));
            }
        }

        private ICommand _CheckedUnitTypeEvent;
        public ICommand CheckedUnitTypeEvent
        {
            get
            {
                return _CheckedUnitTypeEvent ??
                        (_CheckedUnitTypeEvent = new RelayCommand<CheckBox>(UnitTypeFilter));
            }
        }

        private ICommand _CombinedTowerEvent;
        public ICommand CombinedTowerEvent
        {
            get
            {
                return _CombinedTowerEvent ??
                        (_CombinedTowerEvent = new RelayCommand<CheckBox>(FilterByCombinedTower));
            }
        }

        #endregion

        #region Constructor
        public FilterVM()
        {
            if (!DesignerProperties.IsInDesignTool)
            {
                ServiceLocator.Get<ImportVM>().OnDivisionListDataCompleted += new EventHandler<CustomEventArgs<List<string>>>(FilterVM_OnDivisionListDataCompleted);
                LodaData();
            }
        }
        #endregion

        #region Load Fluid, UnitType and Faclity Type static Data
        private void LodaData()
        {
            FluidList = new List<Fluid>()
            {
                new Fluid() { FluidTypeId = FIFPConstants.FLUIDTYPE_OIL, FluidTypeName=FIFPConstants.FLUIDTYPE_OIL_DISPLAY },
                new Fluid() { FluidTypeId=FIFPConstants.FLUIDTYPE_WATER, FluidTypeName=FIFPConstants.FLUIDTYPE_WATER_DISPLAY },
                new Fluid() { FluidTypeId=FIFPConstants.FLUIDTYPE_GAS, FluidTypeName=FIFPConstants.FLUIDTYPE_GAS_DISPLAY }
            };



            UnitTypeList.Add(FIFPConstants.UNITTYPE_RADIAL);
            UnitTypeList.Add(FIFPConstants.UNITTYPE_TOWER);
            UnitTypeList.Add(FIFPConstants.UNITTYPE_WELL);
            UnitTypeList.Add(FIFPConstants.UNITTYPE_PIPELINE);

            FacilityList.Add(FIFPConstants.UNITTYPE_COMPRESSOR);
            FacilityList.Add(FIFPConstants.UNITTYPE_SEPERATOR);


        }
        #endregion

        #region Get Division data from the corresponding view models
        void FilterVM_OnDivisionListDataCompleted(object sender, CustomEventArgs<List<string>> e)
        {
            if (e.Item != null)
            {
                DivisionList.Add("Division");
                DivisionList.AddRange(e.Item);
                SelectedDivision = DivisionList[0];
            }
        }
        #endregion

        #region Filter Appointment By Fluid and Unit Type
        private void FilterAppointmentByFluidAndUnitType(Button btnFilter)
        {
            List<FIFPAppointment> lstAppointments = new List<FIFPAppointment>();
            List<Unit> lstLSDLocations;
            if (ServiceLocator.Get<MainPageVM>().IsImportChecked)
            {
                List<FIFPAppointment> importActivities = ServiceLocator.Get<ImportVM>().ImportPlans;
                if (importActivities != null && importActivities.Count > 0)
                {
                    if (!string.IsNullOrEmpty(SelectedDivision) && SelectedDivision != "Division")
                        lstAppointments = (from item in importActivities
                                           where (item.Start >= StartDate && item.End <= EndDate) && item.Division == SelectedDivision
                                           select item).ToList<FIFPAppointment>();
                    if (selectedFluids != null && selectedFluids.Count > 0 && selectedUnitTypes != null && selectedUnitTypes.Count > 0)

                        lstAppointments = (from item in importActivities
                                           where (item.Start >= StartDate && item.End <= EndDate) && selectedFluids.Contains(item.FluidType) && selectedUnitTypes.Contains(item.UnitType)
                                           select item).ToList<FIFPAppointment>();
                    else if (selectedFluids != null && selectedFluids.Count > 0)

                        lstAppointments = (from item in importActivities
                                           where (item.Start >= StartDate && item.End <= EndDate) && selectedFluids.Contains(item.FluidType)
                                           select item).ToList<FIFPAppointment>();
                    else if (selectedUnitTypes != null && selectedUnitTypes.Count > 0)
                        lstAppointments = (from item in importActivities
                                           where (item.Start >= StartDate && item.End <= EndDate) && selectedUnitTypes.Contains(item.UnitType)
                                           select item).ToList<FIFPAppointment>();
                    else
                        lstAppointments = importActivities;
                    LoadTimelineView(lstAppointments);
                }
            }
            else if (ServiceLocator.Get<MainPageVM>().IsLinkedSDChecked)
            {
                lstLSDLocations = new List<Unit>();
                List<Unit> lsdActivities = new List<Unit>(ServiceLocator.Get<ShutdownMngVM>().LinkedShutdownLocations);
                if (lsdActivities != null && lsdActivities.Count > 0)
                {

                    if (selectedFluids != null && selectedFluids.Count > 0 && selectedUnitTypes != null && selectedUnitTypes.Count > 0)

                        lstLSDLocations = (from item in lsdActivities
                                           where selectedFluids.Any(s => s.Equals(item.FluidType)) && selectedUnitTypes.Any(s => s.Equals(item.UnitType))
                                           select item).ToList<Unit>();
                    else if (selectedFluids != null && selectedFluids.Count > 0)

                        lstLSDLocations = (from item in lsdActivities
                                           where selectedFluids.Any(s => s.Equals(item.FluidType))
                                           select item).ToList<Unit>();
                    else if (selectedUnitTypes != null && selectedUnitTypes.Count > 0)
                        lstLSDLocations = (from item in lsdActivities
                                           where selectedUnitTypes.Any(s => s.Equals(item.UnitType))
                                           select item).ToList<Unit>();
                    else
                        lstLSDLocations = lsdActivities;

                    ServiceLocator.Get<ShutdownMngVM>().FilteredLSDLocations = new ObservableCollection<Unit>(lstLSDLocations);
                }
            }
            else if (ServiceLocator.Get<MainPageVM>().IsOptMngChecked)
            {
                lstLSDLocations = new List<Unit>();
                List<Unit> lsdActivities = new List<Unit>(ServiceLocator.Get<OptMngVM>().LinkedShutdownLocations);
                if (lsdActivities != null && lsdActivities.Count > 0)
                {

                    if (selectedFluids != null && selectedFluids.Count > 0 && selectedUnitTypes != null && selectedUnitTypes.Count > 0)

                        lstLSDLocations = (from item in lsdActivities
                                           where selectedFluids.Any(s => s.Equals(item.FluidType)) && selectedUnitTypes.Any(s => s.Equals(item.UnitType))
                                           select item).ToList<Unit>();
                    else if (selectedFluids != null && selectedFluids.Count > 0)

                        lstLSDLocations = (from item in lsdActivities
                                           where selectedFluids.Any(s => s.Equals(item.FluidType))
                                           select item).ToList<Unit>();
                    else if (selectedUnitTypes != null && selectedUnitTypes.Count > 0)
                        lstLSDLocations = (from item in lsdActivities
                                           where selectedUnitTypes.Any(s => s.Equals(item.UnitType))
                                           select item).ToList<Unit>();
                    else
                        lstLSDLocations = lsdActivities;

                    ServiceLocator.Get<OptMngVM>().FilteredLSDLocations = new ObservableCollection<Unit>(lstLSDLocations);
                }
            }

            //ServiceLocator.Get<AppointmentVM>().FilteredAppointments = lstAppointments;

        }

        #endregion

        #region Division Filter
        private void DivisionFilter(ComboBox cmbDivision)
        {
            List<FIFPAppointment> filteredAppointments = new List<FIFPAppointment>();
            List<FIFPAppointment> appointments = new List<FIFPAppointment>();

            if (ServiceLocator.Get<MainPageVM>().IsImportChecked)
                appointments = ServiceLocator.Get<ImportVM>().ImportPlans;
            else if (ServiceLocator.Get<MainPageVM>().IsLinkedSDChecked)
                appointments = ServiceLocator.Get<ShutdownMngVM>().ActivityListWithSelectedUnit;
            else if (ServiceLocator.Get<MainPageVM>().IsOptMngChecked)
                appointments = ServiceLocator.Get<OptMngVM>().ActivityListWithSelectedUnit;

            if (appointments != null && appointments.Count > 0)
            {
                if (SelectedDivision != null && SelectedDivision == "Division")
                    filteredAppointments = appointments;
                else
                    filteredAppointments = (from item in appointments
                                            where item.Division == SelectedDivision
                                            select item).ToList<FIFPAppointment>();
            }
            if (ServiceLocator.Get<MainPageVM>().IsLinkedSDChecked)
                ServiceLocator.Get<ShutdownMngVM>().FilteredActivityListWithSelectedUnit = new ObservableCollection<FIFPAppointment>(filteredAppointments);
            else if (ServiceLocator.Get<MainPageVM>().IsOptMngChecked)
                ServiceLocator.Get<OptMngVM>().FilteredActivityListWithSelectedUnit = new ObservableCollection<FIFPAppointment>(filteredAppointments);
           
            if (ServiceLocator.Get<MainPageVM>().IsLinkedSDChecked || ServiceLocator.Get<MainPageVM>().IsOptMngChecked)
            {
                List<FIFPAppointment> lsdPlans = new List<FIFPAppointment>();
                foreach (FIFPAppointment appointment in filteredAppointments)
                {
                    lsdPlans.Add(appointment);
                    lsdPlans.AddRange(appointment.FilteredLsdPlans);
                }
                LoadTimelineView(lsdPlans);
            }
            else
                LoadTimelineView(filteredAppointments);
        }
        #endregion

        #region LoadTimelineView
        private void LoadTimelineView(List<FIFPAppointment> plans)
        {
            AppointmentGroup appointmentGroup = new AppointmentGroup();
            List<ResourceType> lstResources = new List<ResourceType>();
            List<Resource> unitList = new List<Resource>();
            ResourceType unitType = new ResourceType("Unit");
            unitType.DisplayName = "Unit";
            unitType.Name = "Unit";

            foreach (FIFPAppointment appointment in plans)
            {
                Resource resource = new Resource() { ResourceName = appointment.UnitName, DisplayName = appointment.UnitName, ResourceType = unitType.Name };
                //unitList.Add(resource);
                if (!unitList.Contains(resource))
                {
                    unitList.Add(resource);
                }
                appointment.Resources.Add(resource);
            }

            appointmentGroup.Appointments = new List<FIFPAppointment>(plans);
            unitType.Resources.AddRange(unitList);
            lstResources.Add(unitType);


            appointmentGroup.ResourceTypes = lstResources;
            appointmentGroup.UnitList = unitList;

            if (OnAppointmentDataCompleted != null)
                OnAppointmentDataCompleted(this, new CustomEventArgs<AppointmentGroup>(appointmentGroup));

        }
        #endregion

        #region Fluid Filter
        private void FluidFilter(CheckBox chkFluid)
        {
            string fluidType = Convert.ToString(chkFluid.Tag);
            if (!string.IsNullOrEmpty(fluidType))
            {
                if (Convert.ToBoolean(chkFluid.IsChecked))
                {
                    selectedFluids.Add(fluidType);
                }
                else
                {
                    selectedFluids.Remove(fluidType);
                }
            }
        }
        #endregion

        #region UnitType Filter
        private void UnitTypeFilter(CheckBox chkUnitType)
        {
            string unitType = Convert.ToString(chkUnitType.Tag);
            if (!string.IsNullOrEmpty(unitType))
            {
                if (Convert.ToBoolean(chkUnitType.IsChecked))
                {
                    selectedUnitTypes.Add(unitType);
                }
                else
                {
                    selectedUnitTypes.Remove(unitType);
                }
            }
        }
        #endregion

        #region Filter by Compressor
        private void FilterByCombinedTower(CheckBox chkCT)
        {
            IsCombinedTowerChecked = Convert.ToBoolean(chkCT.IsChecked) ? true : false;
            if (OnCombinedTowerClick != null)
                OnCombinedTowerClick(this, null);

            //ServiceLocator.Get<ShutdownMngVM>().FilteredLSDLocations = from item in ServiceLocator.Get<ShutdownMngVM>().LinkedShutdownLocations

        }
        #endregion
    }
}
